package com.yeziji.common;

import cn.hutool.core.util.StrUtil;
import com.yeziji.utils.expansion.Opt2;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import javax.annotation.Nonnull;
import java.util.Date;

/**
 * 通用查询对象
 *
 * @author hwy
 * @since 2023/09/05 2:11
 **/
@Data
@SuperBuilder
@NoArgsConstructor
public abstract class CommonQuery<T> {
    /**
     * 主键 id
     */
    private Long id;

    /**
     * 任意查询关键字
     */
    private String keyword;

    /**
     * 查询数据的起始时间
     */
    private Date startTime;

    /**
     * 查询数据的最后时间
     */
    private Date endTime;

    /**
     * 分页数据
     */
    private IPage<T> page;

    /**
     * 获取查询的类型
     *
     * @return {@link Class<T>} 用于强制泛型
     */
    public abstract Class<T> getQueryClass();

    /**
     * 如果为 null 返回默认分页
     *
     * @return {@link IPage} 分页数据
     */
    public IPage<T> getOrDefaultPage() {
        return Opt2.nullElse(this.page, IPage.defaultPage());
    }

    /**
     * 如果为 null 返回默认分页
     *
     * @return {@link IPage} 分页数据
     */
    public <O> IPage<O> getOrDefaultPage(Class<O> clazz) {
        return Opt2.nullElse(this.getPage(clazz), IPage.defaultPage());
    }

    /**
     * 支持转换为其他泛型
     *
     * @param clazz 其他泛型 class
     * @param <O>   其他泛型
     * @return {@link Class} 其他泛型类 class
     */
    public <O> Class<O> getQueryClass(@Nonnull Class<O> clazz) {
        return clazz;
    }

    /**
     * 支持转换为其他泛型
     *
     * @param clazz 其他泛型 class
     * @param <O>   其他泛型
     * @return {@link IPage} 其他泛型分页对象
     */
    public <O> IPage<O> getPage(Class<O> clazz) {
        if (this.page != null) {
            return new IPage<>(this.page.getPageNumber(), this.page.getPageSize());
        }
        return null;
    }

    /**
     * 判断是否有 id
     *
     * @return {@link Boolean} 是否有 id
     */
    public boolean isHasId() {
        return this.id != null;
    }

    /**
     * 判断是否入参了任意关键字
     *
     * @return {@link Boolean} 是否有关键字
     */
    public boolean isHasKeyword() {
        return StrUtil.isNotBlank(this.keyword);
    }

    /**
     * 判断是否入参了查询起始时间
     *
     * @return {@link Boolean} 是否入参起始时间
     */
    public boolean isHasStartTime() {
        return this.startTime != null;
    }

    /**
     * 判断是否入参了查询终止时间
     *
     * @return {@link Boolean} 是否入参终止时间
     */
    public boolean isHasEndTime() {
        return this.endTime != null;
    }
}
